package com.bestcem.xm.survey.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.bestcem.xm.common.core.exception.BusinessException;
import com.bestcem.xm.component.mybatis.service.impl.XmServiceImpl;
import com.bestcem.xm.qdes.grpc.v1.services.Project;
import com.bestcem.xm.qdes.grpc.v1.services.Quota;
import com.bestcem.xm.survey.controller.param.QuotaProgressParam;
import com.bestcem.xm.survey.entity.SurveyQuotaProgress;
import com.bestcem.xm.survey.entity.SurveyRespondent;
import com.bestcem.xm.survey.grpc.client.QdesGrpcClient;
import com.bestcem.xm.survey.mapper.SurveyQuotaProgressMapper;
import com.bestcem.xm.survey.mapper.SurveyRespondentMapper;
import com.bestcem.xm.survey.service.SurveyQuotaConditionService;
import com.bestcem.xm.survey.service.SurveyQuotaProgressService;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static com.bestcem.xm.qdes.grpc.v1.services.ProjectStatus.PROJECT_STATUS_DELETED;
import static com.bestcem.xm.qdes.grpc.v1.services.ProjectStatus.PROJECT_STATUS_DELETED2;
import static com.bestcem.xm.qdes.grpc.v1.services.QuotaQuotaType.QUOTA_QUOTA_TYPE_CROSS;
import static com.bestcem.xm.survey.grpc.v1.services.RespondentDataStatus.RESPONDENT_DATA_STATUS_FORMAL;
import static com.bestcem.xm.survey.grpc.v1.services.RespondentStatus.RESPONDENT_STATUS_FINISH;

/**
* @author guita
* @description 针对表【ds_survey_quotaprogress】的数据库操作Service实现
* @createDate 2023-01-09 15:15:37
*/
@Service
@Slf4j
@RequiredArgsConstructor
public class SurveyQuotaProgressServiceImpl extends XmServiceImpl<SurveyQuotaProgressMapper, SurveyQuotaProgress>
    implements SurveyQuotaProgressService{
    private @NonNull SurveyRespondentMapper surveyRespondentMapper;
    private @NonNull QdesGrpcClient qdesGrpcClient;
    private @NonNull SurveyQuotaConditionService surveyQuotaConditionService;

    @Override
    public JSONObject getQuotaProgressShare(String projectId) {
        // 配额分享
        Project project = qdesGrpcClient.getProject(projectId);
        if (project == null) {
            throw new BusinessException("Project not found");
        }

        LambdaQueryWrapper<SurveyQuotaProgress> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SurveyQuotaProgress::getProjectId, projectId);
        List<SurveyQuotaProgress> surveyQuotaProgresses = baseMapper.selectList(wrapper);
        if (CollectionUtils.isEmpty(surveyQuotaProgresses)) {
            return new JSONObject();
        }
        JSONObject ret = new JSONObject();
        ret.put("quotaprogress", surveyQuotaProgresses.get(0));
        ret.put("project_name", project.getTitle());
        return ret;
    }

    @Override
    public JSONObject getQuotaProgress(String projectId) {
        // 配额分享
        Project project = qdesGrpcClient.getProject(projectId);
        if (project == null) {
            throw new BusinessException("Project not found");
        }
        List<JSONObject> quotaList = quotaProgressBuild(projectId);
        LambdaQueryWrapper<SurveyRespondent> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SurveyRespondent::getProjectId, projectId);
        wrapper.eq(SurveyRespondent::getDataStatus, RESPONDENT_DATA_STATUS_FORMAL.getNumber());
        Long num = surveyRespondentMapper.selectCount(wrapper);

        JSONObject ret = new JSONObject();
        ret.put("quota_list", quotaList);
        ret.put("num", num);
        ret.put("project_name", project.getTitle());
        return ret;
    }

    @Override
    public JSONObject getQuotaProgressPublic(String projectId) {
        // 配额分享
        Project project = qdesGrpcClient.getProject(projectId);
        if (project == null) {
            throw new BusinessException("Project not found");
        }
        List<JSONObject> quotaList = quotaProgressBuild(projectId);
        LambdaQueryWrapper<SurveyRespondent> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SurveyRespondent::getProjectId, projectId);
        wrapper.eq(SurveyRespondent::getDataStatus, RESPONDENT_DATA_STATUS_FORMAL.getNumber());
        wrapper.eq(SurveyRespondent::getStatus, RESPONDENT_STATUS_FINISH.getNumber());
        Long num = surveyRespondentMapper.selectCount(wrapper);

        JSONObject ret = new JSONObject();
        ret.put("quota_list", quotaList);
        ret.put("num", num);
        ret.put("project_name", project.getTitle());
        return ret;
    }

    @Override
    public JSONObject getQuotaProgressValid(String projectId) {
        // 分享链接验证：
        //        1、查看权限：公开、非公开密码
        //        2、链接有效期： 永久有效、有效期范围
        //        3、是否存在配额
        JSONObject ret = new JSONObject();
        Project project = qdesGrpcClient.getProject(projectId);
        if (project == null) {
            throw new BusinessException("Project not found");
        }
        boolean hasProject = PROJECT_STATUS_DELETED.getNumber() != project.getStatusValue()
            && PROJECT_STATUS_DELETED2.getNumber() != project.getStatusValue();
        LambdaQueryWrapper<SurveyQuotaProgress> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SurveyQuotaProgress::getProjectId, projectId);
        List<SurveyQuotaProgress> surveyQuotaProgresses = baseMapper.selectList(wrapper);
        if (CollectionUtils.isEmpty(surveyQuotaProgresses)) {
            List<Quota> quotaList = qdesGrpcClient.getQuotaList(projectId, null);
            boolean hasQuota = !CollectionUtils.isEmpty(quotaList);
            ret.put("has_quota", hasQuota);
            ret.put("has_password", false);
            ret.put("date_valid", true);
            ret.put("project_name", project.getTitle());
            ret.put("has_project", hasProject);
            return ret;
        }
        JSONObject sdict = validQuotaShare(surveyQuotaProgresses.get(0), projectId);
        ret.put("has_quota", sdict.getBoolean("has_quota"));
        ret.put("has_password", sdict.getBoolean("has_password"));
        ret.put("date_valid", sdict.getBoolean("date_valid"));
        ret.put("project_name", project.getTitle());
        ret.put("has_project", hasProject);
        return ret;
    }

    @Override
    public JSONObject checkQuotaProgressValid(String projectId, JSONObject param) {
        log.info("Now to checkQuotaProgressValid, projectId = {}", projectId);
        JSONObject resJson = new JSONObject();
        resJson.put("valid", false);
        SurveyQuotaProgress progress = baseMapper.selectOne(new LambdaQueryWrapper<SurveyQuotaProgress>()
            .eq(SurveyQuotaProgress::getProjectId, projectId).last("limit 1"));
        if (progress != null) {
            resJson.put("valid", progress.getPassword().equals(param.getString("password")));
        } else {
            throw new BusinessException("quotaprogress not found");
        }
        return resJson;
    }

    @Override
    public JSONObject saveQuotaProgress(String projectId, QuotaProgressParam param) {
        // 保存配额分享页
        LambdaQueryWrapper<SurveyQuotaProgress> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SurveyQuotaProgress::getProjectId, projectId);
        List<SurveyQuotaProgress> surveyQuotaProgresses = baseMapper.selectList(queryWrapper);
        String id;
        if (CollectionUtils.isNotEmpty(surveyQuotaProgresses)) {
            SurveyQuotaProgress progress = surveyQuotaProgresses.get(0);
            if (param.getPassword() != null) {
                progress.setPassword(param.getPassword());
            }
            if (param.getStarttime() != null) {
                progress.setStarttime(param.getStarttime());
            }
            if (param.getEndtime() != null) {
                progress.setEndtime(param.getEndtime());
            }
            progress.setUpdatedDt(LocalDateTime.now());
            baseMapper.updateById(progress);
            id = progress.getId();
        } else {
            SurveyQuotaProgress progress = new SurveyQuotaProgress();
            progress.setEndtime(param.getEndtime());
            progress.setStarttime(param.getStarttime());
            progress.setPassword(param.getPassword());
            progress.setPrivacy(param.getPrivacy());
            progress.setProjectId(projectId);
            baseMapper.insert(progress);
            id = progress.getId();
        }
        JSONObject ret = new JSONObject();
        ret.put("id", id);
        return ret;
    }

    private JSONObject validQuotaShare(SurveyQuotaProgress quotaprogress, String projectId) {
        boolean hasPassword = StringUtils.isNotEmpty(quotaprogress.getPassword());
        String starttime = quotaprogress.getStarttime();
        String endtime = quotaprogress.getEndtime();
        // 存储的时间是字符串，这里还是切片一下比较好
        boolean dateValid = true;
        long nowTimestamp = System.currentTimeMillis();
        if (StringUtils.isNotEmpty(starttime)) {
            // 时间有的是字符串有的是日期类型
            starttime = starttime.substring(0, 10);
            if (starttime.contains("T")) {
                starttime = starttime.split("T")[0];
            }
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            // 转换为时间戳
            try {
                Date date = simpleDateFormat.parse(starttime + " 00:00:00");
                long time = date.getTime();
                if (nowTimestamp < time) {
                    dateValid = false;
                }
            } catch (ParseException e) {
                log.error("Parse time error, startTime = {}", starttime);
            }
        }
        if (StringUtils.isNotEmpty(endtime)) {
            // 时间有的是字符串有的是日期类型
            endtime = endtime.substring(0, 10);
            if (endtime.contains("T")) {
                endtime = endtime.split("T")[0];
            }
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            // 转换为时间戳
            try {
                Date date = simpleDateFormat.parse(endtime + " 23:59:59");
                long time = date.getTime();
                if (nowTimestamp > time) {
                    dateValid = false;
                }
            } catch (ParseException e) {
                log.error("Parse time error, endTime = {}", endtime);
            }
        }
        // 3
        List<Quota> quotaList = qdesGrpcClient.getQuotaList(projectId, null);
        boolean hasQuota = CollectionUtils.isNotEmpty(quotaList);
        JSONObject ret = new JSONObject();
        ret.put("has_quota", hasQuota);
        ret.put("has_password", hasPassword);
        ret.put("date_valid", dateValid);
        return ret;
    }

    private List<JSONObject> quotaProgressBuild(String projectId) {
        List<Quota> quotaList = qdesGrpcClient.getQuotaList(projectId, null);
        List<JSONObject> quotas = new ArrayList<>();
        if (CollectionUtils.isEmpty(quotaList)) {
            return quotas;
        }
        quotaList.forEach(quota -> {
            JSONObject quotaJs = new JSONObject();
            quotaJs.put("name", quota.getName());
            quotaJs.put("id", quota.getId());
            quotaJs.put("project_id", quota.getProjectId());
            quotaJs.put("quota_type", quota.getQuotaTypeValue());
            quotaJs.put("col1", StringUtils.isEmpty(quota.getCol1()) ? new ArrayList<>() : JSONArray.parseArray(quota.getCol1()));
            quotaJs.put("col2", StringUtils.isEmpty(quota.getCol2()) ? new ArrayList<>() : JSONArray.parseArray(quota.getCol2()));
            quotaJs.put("row1", StringUtils.isEmpty(quota.getRow1()) ? new ArrayList<>() : JSONArray.parseArray(quota.getRow1()));
            quotaJs.put("row2", StringUtils.isEmpty(quota.getRow2()) ? new ArrayList<>() : JSONArray.parseArray(quota.getRow2()));
            if (quota.getQuotaTypeValue() == QUOTA_QUOTA_TYPE_CROSS.getNumber()) {
                JSONObject crossJs = surveyQuotaConditionService.genCrossQuotaDataCommon(quota.getId());
                quotaJs.put("define_num_list", crossJs.get("define_num_list"));
                quotaJs.put("num_list", crossJs.get("num_list"));
            } else {
                // 普通配额
                List<JSONObject> normalJs = surveyQuotaConditionService.genNormalQuotaDataCommon(quota.getId());
                quotaJs.put("trlist", normalJs);
            }
            quotaJs.remove("quota_cond_list");
            quotaJs.remove("ava_qgid_list");
            quotas.add(quotaJs);
        });
        return quotas;
    }
}




